<?php

namespace log;

require_once(APP_ROOT . '/modules/log/logEntry.php');
require_once(APP_ROOT . '/modules/log/logCommon.php');

/**
 * Logging system.
 * @note singleton class.
 * @warning if the initialization of the log system fails an assert will be
 *  triggered => the application is going to quit.
 */
class Log
{
    /**
     * Indicate that the logs system is currently active.
     */
    private static $isActive;

    /**
     * Config data.
     */
    private static $config;

    //--------------------------------------------------------------------------
    /**
     * Initialize logs system.
     * @return TRUE=>success | FALSE=>fail.
     */
    private static function init()
    {
        // Store configurations.
        self::$config = json_decode(
            file_get_contents(APP_ROOT . "/modules/config/log/config.json", TRUE), TRUE);
        assert((!is_null(self::$config)) && (is_array(self::$config)));
        assert(array_key_exists("console", self::$config));
        assert(array_key_exists("file", self::$config));
        assert(array_key_exists("filename", self::$config));

        // Activate system.
        self::$isActive = TRUE;

        return TRUE;
    }
    //--------------------------------------------------------------------------

    //--------------------------------------------------------------------------
    /**
     * Add log entry.
     * @param[in] module module identifier.
     * @param[in] filename file name.
     * @param[in] line file line number.
     * @param[in] function function name.
     * @param[in] type log type identifier.
     * @param[in] msg log message.
     */
    public static function LOG($module, $filename, $line, $function, $type,
                               $msg)
    {
        $entry = null; // New log entry.
        $mod   = null; // Module config.

        // Check requirements.
        if((!self::$isActive) || (is_null(self::$config))) {
            self::init();
        }
        $mod = self::$config[strtolower(LogCommon::$logModuleStr[$module])];
        if(!$mod[LogCommon::$logTypeStr[$type]]) {
            return;
        }

        // Generate entry.
        $entry            = new LogEntry();
        $entry->file      = $filename;
        $entry->function  = $function;
        $entry->host      = gethostname();
        $entry->line      = $line;
        $entry->module    = $module;
        $entry->msg       = $msg;
        $entry->procid    = getmypid();
        $entry->sysusr    = get_current_user();
        $entry->threadid  = 0;
        $entry->timestamp = time();
        $entry->type      = $type;

        // Print entry.
        $estr = $entry->dump();
        if(empty($estr)) {
            print "Invalid log entry: empty";
            return;
        }
        if(self::$config["console"]) {
            print $estr."\n";
        }
        if(self::$config["file"]) {
            file_put_contents(self::$config["filename"], $estr."\n",
                FILE_USE_INCLUDE_PATH|FILE_APPEND);
        }
    }
    //--------------------------------------------------------------------------

    //--------------------------------------------------------------------------
    public static function LOG_COMMON($type, $msg, $stframe = 1)
    {
        $frame = debug_backtrace($stframe); // Stack frame.
        self::LOG(LogCommon::logCommon,
            ((array_key_exists("file", $frame[$stframe-1]))?($frame[$stframe-1]["file"]):("")),
            ((array_key_exists("line", $frame[$stframe-1]))?($frame[$stframe-1]["line"]):("")),
            ((array_key_exists("function", $frame[$stframe]))?($frame[$stframe]["function"]):("")),
            $type, $msg);
    }
    public static function LOG_COMMON_FB()
    {
        self::LOG_COMMON(LogCommon::logTypeStackTrace, "FUNCTION BEGIN", 2);
    }
    public static function LOG_COMMON_FE()
    {
        self::LOG_COMMON(LogCommon::logTypeStackTrace, "FUNCTION END", 2);
    }
    //--------------------------------------------------------------------------

    //--------------------------------------------------------------------------
    public static function LOG_INVENTORY($type, $msg, $stframe = 1)
    {
        $frame = debug_backtrace($stframe); // Stack frame.
        self::LOG(LogCommon::logInventory,
            ((array_key_exists("file", $frame[$stframe-1]))?($frame[$stframe-1]["file"]):("")),
            ((array_key_exists("line", $frame[$stframe-1]))?($frame[$stframe-1]["line"]):("")),
            ((array_key_exists("function", $frame[$stframe]))?($frame[$stframe]["function"]):("")),
            $type, $msg);
    }
    public static function LOG_INVENTORY_FB()
    {
        self::LOG_INVENTORY(LogCommon::logTypeStackTrace, "FUNCTION BEGIN", 2);
    }
    public static function LOG_INVENTORY_FE()
    {
        self::LOG_INVENTORY(LogCommon::logTypeStackTrace, "FUNCTION END", 2);
    }
    //--------------------------------------------------------------------------

    //--------------------------------------------------------------------------
    public static function LOG_PERSISTANCE($type, $msg, $stframe = 1)
    {
        $frame = debug_backtrace($stframe); // Stack frame.
        self::LOG(LogCommon::logPersistance,
            ((array_key_exists("file", $frame[$stframe-1]))?($frame[$stframe-1]["file"]):("")),
            ((array_key_exists("line", $frame[$stframe-1]))?($frame[$stframe-1]["line"]):("")),
            ((array_key_exists("function", $frame[$stframe]))?($frame[$stframe]["function"]):("")),
            $type, $msg);
    }
    public static function LOG_PERSISTANCE_FB()
    {
        self::LOG_PERSISTANCE(LogCommon::logTypeStackTrace, "FUNCTION BEGIN", 2);
    }
    public static function LOG_PERSISTANCE_FE()
    {
        self::LOG_PERSISTANCE(LogCommon::logTypeStackTrace, "FUNCTION END", 2);
    }
    //--------------------------------------------------------------------------

    //--------------------------------------------------------------------------
    public static function LOG_WEBROOTWS($type, $msg, $stframe = 1)
    {
        $frame = debug_backtrace($stframe); // Stack frame.
        self::LOG(LogCommon::logWebrootWs,
            ((array_key_exists("file", $frame[$stframe-1]))?($frame[$stframe-1]["file"]):("")),
            ((array_key_exists("line", $frame[$stframe-1]))?($frame[$stframe-1]["line"]):("")),
            ((array_key_exists("function", $frame[$stframe]))?($frame[$stframe]["function"]):("")),
            $type, $msg);
    }
    public static function LOG_WEBROOTWS_FB()
    {
        self::LOG_WEBROOTWS(LogCommon::logTypeStackTrace, "FUNCTION BEGIN", 2);
    }
    public static function LOG_WEBROOTWS_FE()
    {
        self::LOG_WEBROOTWS(LogCommon::logTypeStackTrace, "FUNCTION END", 2);
    }
    //--------------------------------------------------------------------------

    //--------------------------------------------------------------------------
    public static function LOG_WEBROOTHTML($type, $msg, $stframe = 1)
    {
        $frame = debug_backtrace($stframe); // Stack frame.
        self::LOG(LogCommon::logWebrootHtml,
            ((array_key_exists("file", $frame[$stframe-1]))?($frame[$stframe-1]["file"]):("")),
            ((array_key_exists("line", $frame[$stframe-1]))?($frame[$stframe-1]["line"]):("")),
            ((array_key_exists("function", $frame[$stframe]))?($frame[$stframe]["function"]):("")),
            $type, $msg);
    }
    public static function LOG_WEBROOTHTML_FB()
    {
        self::LOG_WEBROOTHTML(LogCommon::logTypeStackTrace, "FUNCTION BEGIN", 2);
    }
    public static function LOG_WEBROOTHTML_FE()
    {
        self::LOG_WEBROOTHTML(LogCommon::logTypeStackTrace, "FUNCTION END", 2);
    }
    //--------------------------------------------------------------------------

    //--------------------------------------------------------------------------
    public static function LOG_SESSION($type, $msg, $stframe = 1)
    {
        $frame = debug_backtrace($stframe); // Stack frame.
        self::LOG(LogCommon::logSession,
            ((array_key_exists("file", $frame[$stframe-1]))?($frame[$stframe-1]["file"]):("")),
            ((array_key_exists("line", $frame[$stframe-1]))?($frame[$stframe-1]["line"]):("")),
            ((array_key_exists("function", $frame[$stframe]))?($frame[$stframe]["function"]):("")),
            $type, $msg);
    }
    public static function LOG_SESSION_FB()
    {
        self::LOG_SESSION(LogCommon::logTypeStackTrace, "FUNCTION BEGIN", 2);
    }
    public static function LOG_SESSION_FE()
    {
        self::LOG_SESSION(LogCommon::logTypeStackTrace, "FUNCTION END", 2);
    }
    //--------------------------------------------------------------------------

}
